package containerleran;

import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;

public class MyQueue<E> implements Queue<E> {

	Term<E> head;
	Term<E> tail;
//	Term t;
	int size;
	public MyQueue(E e){
		Term<E> t = new Term<E>(this.tail,this.head,e);
		this.tail = new Term<E>(null,t,null);
		this.head = new Term<E>(t,null,null);
		size = 1;
	}
	public MyQueue(Term<E> head,Term<E> tail,int size){
		
	}
	public MyQueue(){
		size = 0;
		this.tail =new Term<E>(null);
		this.head = new Term<E>(null);
		this.tail.next = this.head;
		this.head.previous = this.tail;
	}
	@Override
	public int size() {
		// TODO Auto-generated method stub
		return size;
	}

	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return (size <=0);
	}

	private  MyQueue<E> getMyQueue(){
		MyQueue<E> mq = new MyQueue<E>();
		mq.head = this.head;
		mq.tail = this.tail;
		mq.size = this.size;
		return mq;
	}
	@Override
	public boolean contains(Object o) {
		// TODO Auto-generated method stub
		if(o!=null){
			if(this.head != null){
				int i = 0;
				Term<E> t = this.head;
				while(t.previous != null &&t.previous != this.tail){
					if(i>this.size){
						break;
					}
					if(o.equals(t.previous.element)){
						return true;
					}
					t = t.previous;
				}
			}
			else{
				return false;
			}
		}
		else{
			throw new NullPointerException();//thinking in java says it is not necessary
		}
		return false;
	}

	@Override
	public Iterator<E> iterator() {		
		return new myIterator<E>(this.getMyQueue());
	}

	@Override
	public Object[] toArray() {
		// TODO Auto-generated method stub
		Object[]t =  new Object[size];
		int i = 0;
		Term<E> term = this.head;
		if(this!= null && this.head != null){
			while(term.previous != null && term.previous!= this.tail){
				if(i>=t.length||i>=this.size){
					break;
				}
				t[i] = term.previous.element;
				term = term.previous;
				i++;
			}
			
		}
		return t;
	}

	@Override
	public <T> T[] toArray(T[] a) {
		// TODO Auto-generated method stub
/*		E[]t = ((E[]) new Object[size]);
		int i = 0;
		Term<E> term = this.head;
		if(this!= null && this.head != null){
			while(term.previous != null && term.previous!= this.tail){
				if(i>=t.length-1||i>=this.size){
					break;
				}
				t[i] = term.previous.element;
				i++;
			}
			
		}
		if(t !=null && t.length>0&&((Object)a == (Object)Object[].class)){
			return (T[])t;
		}
		else{
		return null;
		}*/
		return null;
	}
	
	@Override
	public boolean remove(Object o) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean containsAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean addAll(Collection<? extends E> c) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean removeAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean retainAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void clear() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean add(E e) {
		// TODO Auto-generated method stub
		if(this == null){
			throw new NullPointerException();
		}
		if(this.tail != null){
			if(this.tail .addBefore(new Term<E>(e))){
				this.size++;		
				return true;
			}else{
				//throw new Exception(); 
				return false;	
			}
		}
		return false;
	}

	@Override
	public boolean offer(E e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public E remove() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public E poll() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public E element() {
		// TODO Auto-generated method stub
		if(this.head.previous != this.tail){
			return this.head.previous.element;
		}
		else{
			return null;
		}
	}

	@Override
	public E peek() {
		// TODO Auto-generated method stub
//		LinkedList<String> l = new LinkedList<String>();
		return null;
	}
	public void doPrint(){
		int i = 0;
		Term<E> t = head;
		if(t != null){
			while(t.previous!= this.tail){
				i++;				
				if(i>size){
					System.out.println("wrong size = "+size+"i = "+i);
					return;
				}
				System.out.println(t.previous.element);
				t = t.previous;
			}
		}
	}

	private static class Term<E>{
		private Term<E> previous ;
		private Term<E> next;
		private E element;
		Term(Term<E> p,Term<E> n,E e){
			this.previous = p;
			this.next = n;
			this.element = e;
		}
		Term (E e){
			this.previous = this;
			this.next = this;
			this.element = e;
		}
		private boolean addBefore(Term<E> t){
			
			if(this.next != null){
				t.next = this.next;
				t.previous = this;				
				this.next.previous = t;
				this.next = t;
				return true;
			}
			return false;
		}
	}
	private static class myIterator<E> implements Iterator<E>{

		private Object[] element;
		int size;
		int point;
		public myIterator(MyQueue<E> mq){
			element = mq.toArray();	
			size = mq.size;
			point = 0;
		}
		@Override
		public boolean hasNext() {
			// TODO Auto-generated method stub
			if(size>0 && element!=null&&element.length>0&&point<size&&point<element.length)
				return true;
			return false;
		}

		@Override
		public void remove() {
			// TODO Auto-generated method stub
			point ++;
		}
		
		@SuppressWarnings("unchecked")
		@Override
		public E next() {
			// TODO Auto-generated method stub
			if(hasNext()){
				point ++;
//				if(element[point-1] instanceof E)
				return (E)element[point-1];
			}

			return null;
		}
		
	}
	
}

